package cn.changein.framework.util;

import lombok.extern.slf4j.Slf4j;

import javax.annotation.PostConstruct;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**

 * @version V1.0
 * @Description: TODO(线程池 Timer / TimerTask类似, 解决那些需要任务重复执行的问题)
 * @Title: ScheduledThreadManager
 * @Package cn.pw.common
 * @date 2020/10/30
 */
@Slf4j
public class ScheduledExecutorThreadManager {

    private static ScheduledThreadPoolExecutor scheduledThreadPool;

    @PostConstruct
    private synchronized static void init() {
        if (scheduledThreadPool == null) {
            int cpuNum = Runtime.getRuntime().availableProcessors(); // 核心线程数为 CPU 数*2
            log.info("init scheduledThreadPool cpuNum={}", cpuNum);
            int corePoolSize = cpuNum * 2;
            scheduledThreadPool = new ScheduledThreadPoolExecutor(corePoolSize);
        }
    }

    public static ScheduledExecutorService getScheduledThreadPool() {
        if (scheduledThreadPool == null) {
            init();
        }
        return scheduledThreadPool;
    }

    /**
     * @Description: 实现周期性执行任务调度
     * @return: void
     * @Date:2020/10/31 9:53
     * @Param: [runnable, initialDelay, period, timeUnit]

     */
    public static void scheduleAtFixedRate(Runnable runnable, long initialDelay,
                                           long period, TimeUnit timeUnit) {
        //initialDelay 初始延迟
        //period 间隔时间
        //timeUnit 时间
        getScheduledThreadPool().scheduleAtFixedRate(runnable, initialDelay, period, timeUnit);
    }

    /**
     * @Description: 实现周期性执行任务调度
     * @return: void
     * @Date:2020/10/31 9:53
     * @Param: [runnable, period, timeUnit]

     */
    public static void scheduleAtFixedRate(Runnable runnable,
                                           long period, TimeUnit timeUnit) {

        scheduleAtFixedRate(runnable, 0, period, timeUnit);
    }

    /**
     * @Description: 延迟多少时间执行一次
     * @return: void
     * @Date:2020/10/31 10:21
     * @Param: [runnable, delay, timeUnit]

     */
    public static void schedule(Runnable runnable,
                                long delay, TimeUnit timeUnit) {
        getScheduledThreadPool().schedule(runnable, delay, timeUnit);
    }

    public static void schedule(Runnable runnable, TimeUnit timeUnit) {
        schedule(runnable, 0, timeUnit);
    }
}
